home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / game / shoot / ADoom_src_1_2.lha / ADoom_src / amiga_sound.c < prev    next >
C/C++ Source or Header  |  1998-03-05  |  22KB  |  717 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5.  
  6. #include <exec/exec.h>
  7. #include <dos/dos.h>
  8. #include <graphics/gfxbase.h>
  9. #include <devices/audio.h>
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/dos.h>
  13. #include <proto/graphics.h>
  14.  
  15. /* #include <math.h> */
  16.  
  17. #include "z_zone.h"
  18.  
  19. #include "i_system.h"
  20. #include "i_sound.h"
  21. #include "m_argv.h"
  22. #include "m_misc.h"
  23. #include "w_wad.h"
  24.  
  25. #include "doomdef.h"
  26.  
  27.  
  28. // Any value of numChannels set
  29. // by the defaults code in M_misc is now clobbered by I_InitSound().
  30. // number of channels available for sound effects
  31.  
  32. extern int numChannels;
  33.  
  34. /**********************************************************************/
  35. #define MAXSFXVOICES    16   /* max number of Sound Effects with server */
  36. #define MAXNUMCHANNELS   4   /* max number of Amiga sound channels */
  37. #define CHIP_CACHE_SIZE 12   /* number of waveforms allowed in chipmem */
  38.  
  39. struct chip_cache_info {
  40.   int id;
  41.   ULONG age;
  42.   char *chip_data;
  43.   int len;
  44. };
  45.  
  46. struct channel_info {
  47.   struct MsgPort *audio_mp;
  48.   struct IOAudio *audio_io;
  49.   BOOL sound_in_progress;
  50. };
  51.  
  52. /**********************************************************************/
  53. // The actual lengths of all sound effects.
  54. static int lengths[NUMSFX];
  55.  
  56. static struct MsgPort *audio_mp = NULL;
  57. static struct IOAudio *audio_io = NULL;
  58. static BOOL audio_is_open = FALSE;
  59.  
  60. static struct channel_info channel_info[MAXNUMCHANNELS] = {
  61.   {NULL, NULL, FALSE},
  62.   {NULL, NULL, FALSE},
  63.   {NULL, NULL, FALSE},
  64.   {NULL, NULL, FALSE},
  65. };
  66.  
  67. /* cache up to CHIP_CACHE_SIZE sound effects in chipmem, rest in fastmem */
  68. static struct chip_cache_info chip_cache_info[CHIP_CACHE_SIZE] = {
  69.   {-1, 0, NULL, -1},
  70.   {-1, 0, NULL, -1},
  71.   {-1, 0, NULL, -1},
  72.   {-1, 0, NULL, -1},
  73.   {-1, 0, NULL, -1},
  74.   {-1, 0, NULL, -1},
  75.   {-1, 0, NULL, -1},
  76.   {-1, 0, NULL, -1},
  77.   {-1, 0, NULL, -1},
  78.   {-1, 0, NULL, -1},
  79.   {-1, 0, NULL, -1},
  80.   {-1, 0, NULL, -1}
  81. };
  82.  
  83. static ULONG age = 1;
  84. static UWORD period_table[256];
  85.  
  86. static int changepitch;
  87. /* sampling freq (Hz) for each pitch step when changepitch is TRUE
  88.    calculated from (2^((i-128)/64))*11025
  89.    I'm not sure if this is the right formula */
  90. static UWORD freqs[256] = {
  91.   2756, 2786, 2817, 2847, 2878, 2910, 2941, 2973,
  92.   3006, 3038, 3072, 3105, 3139, 3173, 3208, 3242,
  93.   3278, 3313, 3350, 3386, 3423, 3460, 3498, 3536,
  94.   3574, 3613, 3653, 3692, 3733, 3773, 3814, 3856,
  95.   3898, 3940, 3983, 4027, 4071, 4115, 4160, 4205,
  96.   4251, 4297, 4344, 4391, 4439, 4487, 4536, 4586,
  97.   4635, 4686, 4737, 4789, 4841, 4893, 4947, 5001,
  98.   5055, 5110, 5166, 5222, 5279, 5336, 5394, 5453,
  99.   5513, 5573, 5633, 5695, 5757, 5819, 5883, 5947,
  100.   6011, 6077, 6143, 6210, 6278, 6346, 6415, 6485,
  101.   6556, 6627, 6699, 6772, 6846, 6920, 6996, 7072,
  102.   7149, 7227, 7305, 7385, 7465, 7547, 7629, 7712,
  103.   7796, 7881, 7967, 8053, 8141, 8230, 8319, 8410,
  104.   8501, 8594, 8688, 8782, 8878, 8975, 9072, 9171,
  105.   9271, 9372, 9474, 9577, 9681, 9787, 9893, 10001,
  106.   10110, 10220, 10331, 10444, 10558, 10673, 10789, 10906,
  107.   11025, 11145, 11266, 11389, 11513, 11638, 11765, 11893,
  108.   12023, 12154, 12286, 12420, 12555, 12692, 12830, 12970,
  109.   13111, 13254, 13398, 13544, 13691, 13841, 13991, 14144,
  110.   14298, 14453, 14611, 14770, 14931, 15093, 15258, 15424,
  111.   15592, 15761, 15933, 16107, 16282, 16459, 16639, 16820,
  112.   17003, 17188, 17375, 17564, 17756, 17949, 18144, 18342,
  113.   18542, 18744, 18948, 19154, 19363, 19574, 19787, 20002,
  114.   20220, 20440, 20663, 20888, 21115, 21345, 21578, 21812,
  115.   22050, 22290, 22533, 22778, 23026, 23277, 23530, 23787,
  116.   24046, 24308, 24572, 24840, 25110, 25384, 25660, 25940,
  117.   26222, 26508, 26796, 27088, 27383, 27681, 27983, 28287,
  118.   28595, 28907, 29221, 29540, 29861, 30187, 30515, 30848,
  119.   31183, 31523, 31866, 32213, 32564, 32919, 33277, 33639,
  120.   34006, 34376, 34750, 35129, 35511, 35898, 36289, 36684,
  121.   37084, 37487, 37896, 38308, 38725, 39147, 39573, 40004,
  122.   40440, 40880, 41325, 41775, 42230, 42690, 43155, 43625
  123. };
  124.  
  125. static BPTR asrvr_seg = NULL;
  126.  
  127. static int (* __asm InitServer) (void);
  128. static void (* __asm ExitServer) (void);
  129. static void (* __asm Sfx_SetVol) (register __d0 int vol);
  130. static void (* __asm Sfx_Start) (register __a0 char *wave,
  131.                                  register __d0 int cnum,
  132.                                  register __d1 int step,
  133.                                  register __d2 int vol,
  134.                                  register __d3 int sep,
  135.                                  register __d4 int length);
  136. static void (* __asm Sfx_Update) (register __d0 int cnum,
  137.                                   register __d1 int step,
  138.                                   register __d2 int vol,
  139.                                   register __d3 int sep);
  140. static void (* __asm Sfx_Stop) (register __d0 int cnum);
  141. static int (* __asm Sfx_Done) (register __d0 int cnum);
  142. static void (* __asm Mus_SetVol) (register __d0 int vol);
  143. static int (* __asm Mus_Register) (register __a0 void *musdata);
  144. static void (* __asm Mus_Unregister) (register __d0 int mhndl);
  145. static void (* __asm Mus_Play) (register __d0 int handle,
  146.                                 register __d1 int looping);
  147. static void (* __asm Mus_Stop) (register __d0 int handle);
  148. static void (* __asm Mus_Pause) (register __d0 int handle);
  149. static void (* __asm Mus_Resume) (register __d0 int handle);
  150. static int (* __asm Mus_Done) (register __d0 int handle);
  151.  
  152.  
  153. /**********************************************************************/
  154. //
  155. // This function loads the sound data for sfxname from the WAD lump,
  156. // and returns a ptr to the data in fastmem and its length in len.
  157. //
  158. static void *getsfx (char *sfxname, int *len)
  159. {
  160.   unsigned char*      sfx;
  161.   unsigned char*      paddedsfx;
  162.   int                 i;
  163.   int                 size;
  164.   int                 paddedsize;
  165.   char                name[20];
  166.   int                 sfxlump;
  167.  
  168.   // Get the sound data from the WAD, allocate lump
  169.   //  in zone memory.
  170.   sprintf(name, "ds%s", sfxname);
  171.  
  172.   // Now, there is a severe problem with the
  173.   //  sound handling, in it is not (yet/anymore)
  174.   //  gamemode aware. That means, sounds from
  175.   //  DOOM II will be requested even with DOOM
  176.   //  shareware.
  177.   // The sound list is wired into sounds.c,
  178.   //  which sets the external variable.
  179.   // I do not do runtime patches to that
  180.   //  variable. Instead, we will use a
  181.   //  default sound for replacement.
  182.   if (W_CheckNumForName(name) == -1)
  183.     sfxlump = W_GetNumForName("dspistol");
  184.   else
  185.     sfxlump = W_GetNumForName (name);
  186.  
  187.   size = W_LumpLength (sfxlump);
  188.  
  189.   // Debug.
  190.   // fprintf( stderr, "." );
  191.   // fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
  192.   //         sfxname, sfxlump, size );
  193.   //fflush( stderr );
  194.  
  195.   sfx = (unsigned char*)W_CacheLumpNum (sfxlump, PU_STATIC);
  196.  
  197.   // Allocate from zone memory.
  198.   paddedsfx = (unsigned char*)Z_Malloc (size, PU_STATIC, 0);
  199.   // ddt: (unsigned char *) realloc(sfx, paddedsize+8);
  200.   // This should interfere with zone memory handling,
  201.   //  which does not kick in in the soundserver.
  202.  
  203.   // Now copy and pad.
  204.   for (i = 0; i < size; i++)
  205.     paddedsfx[i] = sfx[i] ^ 0x80;
  206.   /* memcpy (paddedsfx, sfx, size); */
  207.  
  208.   // Remove the cached lump.
  209.   Z_Free( sfx );
  210.  
  211.   // Preserve padded length.
  212.   *len = size;
  213.  
  214.   // Return allocated padded data.
  215.   return (void *) (paddedsfx /* + 8 */);
  216. }
  217.  
  218. /**********************************************************************/
  219. // Init at program start...
  220. void I_InitSound (void)
  221. {
  222.   int i;
  223.   struct channel_info *c;
  224.   UBYTE chans[1];
  225.   ULONG clock_constant;   /* see Amiga Hardware Manual page 141 */
  226.  
  227.   if (M_CheckParm("-nosfx"))
  228.     return;
  229.  
  230.   // Secure and configure sound device first.
  231.   fprintf( stderr, "I_InitSound: ");
  232.  
  233.   if ((asrvr_seg = LoadSeg("PROGDIR:ADoom_SndSrvr")) != NULL) {
  234.     if (*((int *) ((asrvr_seg<<2)+4+4)) == 0x53535256) {
  235.       InitServer = (int (* __asm)(void))((asrvr_seg<<2)+4+8);
  236.       ExitServer = (void (* __asm)(void))((asrvr_seg<<2)+4+12);
  237.       Sfx_SetVol = (void (* __asm)(register __d0 int))((asrvr_seg<<2)+4+16);
  238.       Sfx_Start = (void (* __asm)(register __a0 char *,
  239.                                   register __d0 int,
  240.                                   register __d1 int,
  241.                                   register __d2 int,
  242.                                   register __d3 int,
  243.                                   register __d4 int))((asrvr_seg<<2)+4+20);
  244.       Sfx_Update = (void (* __asm)(register __d0 int,
  245.                                    register __d1 int,
  246.                                    register __d2 int,
  247.                                    register __d3 int))((asrvr_seg<<2)+4+24);
  248.       Sfx_Stop = (void (* __asm)(register __d0 int))((asrvr_seg<<2)+4+28);
  249.       Sfx_Done = (int (* __asm)(register __d0 int))((asrvr_seg<<2)+4+32);
  250.       Mus_SetVol = (void (* __asm)(register __d0 int))((asrvr_seg<<2)+4+36);
  251.       Mus_Register = (int (* __asm)(register __a0 void *))((asrvr_seg<<2)+4+40);
  252.       Mus_Unregister = (void (* __asm)(register __d0 int))((asrvr_seg<<2)+4+44);
  253.       Mus_Play = (void (* __asm)(register __d0 int,
  254.                                  register __d1 int))((asrvr_seg<<2)+4+48);
  255.       Mus_Stop = (void (* __asm)(register __d0 int))((asrvr_seg<<2)+4+52);
  256.       Mus_Pause = (void (* __asm)(register __d0 int))((asrvr_seg<<2)+4+56);
  257.       Mus_Resume = (void (* __asm)(register __d0 int))((asrvr_seg<<2)+4+60);
  258.       Mus_Done = (int (* __asm)(register __d0 int))((asrvr_seg<<2)+4+64);
  259.       if (!InitServer()) {
  260.     Sfx_SetVol(64);
  261.     Mus_SetVol(64);
  262.         numChannels = 16;
  263.       }
  264.       else {            /* couldn't initialize snd server */
  265.         UnLoadSeg(asrvr_seg);
  266.         asrvr_seg = NULL;
  267.       }
  268.     }
  269.     else {            /* not a sound server */
  270.       UnLoadSeg(asrvr_seg);
  271.       asrvr_seg = NULL;
  272.     }
  273.   }
  274.  
  275.   if (asrvr_seg == NULL) {
  276.  
  277.     numChannels = 4;
  278.  
  279.     if ((audio_mp = CreatePort (NULL, 0)) == NULL ||
  280.         (audio_io = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),
  281.                                              MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  282.       I_Error ("CreatePort() or AllocMem() failed");
  283.  
  284.     chans[0] = (1 << numChannels) - 1; /* numchannels Amiga audio channels */
  285.     audio_io->ioa_Request.io_Message.mn_ReplyPort = audio_mp;
  286.     audio_io->ioa_Request.io_Message.mn_Node.ln_Pri = 127;
  287.     audio_io->ioa_AllocKey = 0;
  288.     audio_io->ioa_Data = chans;
  289.     audio_io->ioa_Length = sizeof(chans);
  290.  
  291.     if (OpenDevice (AUDIONAME, 0, (struct IORequest *)audio_io, 0) != 0)
  292.       I_Error ("OpenDevice(\"audio.device\") failed");
  293.     audio_is_open = TRUE;
  294.  
  295.     for (i = 0; i < numChannels; i++) {
  296.       c = &channel_info[i];
  297.       if ((c->audio_mp = CreatePort (NULL, 0)) == NULL ||
  298.           (c->audio_io = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),
  299.                                              MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  300.         I_Error ("CreatePort() or AllocMem() failed");
  301.       *c->audio_io = *audio_io;
  302.       c->audio_io->ioa_Request.io_Message.mn_ReplyPort = c->audio_mp;
  303.       c->audio_io->ioa_Request.io_Unit = (struct Unit *)(1 << i);
  304.     }
  305.   }
  306.  
  307.   if ((GfxBase->DisplayFlags & REALLY_PAL) == 0)
  308.     clock_constant = 3579545;   /* NTSC */
  309.   else
  310.     clock_constant = 3546895;   /* PAL */
  311.   changepitch = M_CheckParm ("-changepitch");
  312.   for (i = 0; i < 256; i++) {
  313.     if (changepitch)
  314.       period_table[i] = ((clock_constant << 1) + freqs[i]) /
  315.                         (((ULONG)freqs[i]) << 1);
  316.     else
  317.       period_table[i] = ((clock_constant << 1) + 11025) / ((11025) << 1);
  318.   }
  319.  
  320.   fprintf (stderr, " configured audio device\n" );
  321.  
  322.  
  323.   // Initialize external data (all sounds) at start, keep static.
  324.   fprintf (stderr, "I_InitSound: ");
  325.  
  326.   for (i = 1; i < NUMSFX; i++) {
  327.     // Alias? Example is the chaingun sound linked to pistol.
  328.     if (!S_sfx[i].link) {
  329.       // Load data from WAD file.
  330.       S_sfx[i].data = getsfx (S_sfx[i].name, &lengths[i]);
  331.     } else {
  332.       // Previously loaded already?
  333.       S_sfx[i].data = S_sfx[i].link->data;
  334.       lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
  335.     }
  336.   }
  337.  
  338.   fprintf (stderr, " pre-cached all sound data\n");
  339.  
  340.   // Finished initialization.
  341.   fprintf (stderr, "I_InitSound: sound module ready\n");
  342. }
  343.  
  344. /**********************************************************************/
  345. // ... update sound buffer and audio device at runtime...
  346. void I_UpdateSound (void)
  347. {
  348.   /* fprintf (stderr, "I_UpdateSound()\n"); */
  349. }
  350.  
  351. /**********************************************************************/
  352. // ... update sound buffer and audio device at runtime...
  353. void I_SubmitSound (void)
  354. {
  355.   /* fprintf (stderr, "I_SubmitSound()\n"); */
  356.   // Write it to DSP device.
  357.   // write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
  358. }
  359.  
  360. /**********************************************************************/
  361. // ... shut down and relase at program termination.
  362. void I_ShutdownSound (void)
  363. {
  364.   int i;
  365.  
  366.   fprintf (stderr, "I_ShutdownSound()\n");
  367.  
  368.   if (asrvr_seg != NULL) {
  369.     ExitServer();
  370.     UnLoadSeg(asrvr_seg);
  371.     asrvr_seg = NULL;
  372.   }
  373.  
  374.   if (audio_is_open) {
  375.     for (i = 0; i < numChannels; i++)
  376.       I_StopSound (i);
  377.     audio_io->ioa_Request.io_Unit = (struct Unit *)
  378.                      ((1 << numChannels) - 1);  /* free numChannels channels */
  379.     CloseDevice ((struct IORequest *)audio_io);
  380.     audio_is_open = FALSE;
  381.   }
  382.   for (i = 0; i < CHIP_CACHE_SIZE; i++) {
  383.     if (chip_cache_info[i].chip_data != NULL) {
  384.       FreeMem (chip_cache_info[i].chip_data, chip_cache_info[i].len);
  385.       chip_cache_info[i].chip_data = NULL;
  386.     }
  387.   }
  388.   for (i = 0; i < MAXNUMCHANNELS; i++) {
  389.     if (channel_info[i].audio_io != NULL) {
  390.       FreeMem (channel_info[i].audio_io, sizeof(struct IOAudio));
  391.       channel_info[i].audio_io = NULL;
  392.     }
  393.     if (channel_info[i].audio_mp != NULL) {
  394.       DeletePort (channel_info[i].audio_mp);
  395.       channel_info[i].audio_mp = NULL;
  396.     }
  397.   }
  398.   if (audio_io != NULL) {
  399.     FreeMem (audio_io, sizeof(struct IOAudio));
  400.     audio_io = NULL;
  401.   }
  402.   if (audio_mp != NULL) {
  403.     DeletePort (audio_mp);
  404.     audio_mp = NULL;
  405.   }
  406. }
  407.  
  408. /**********************************************************************/
  409. /**********************************************************************/
  410. //
  411. //  SFX I/O
  412. //
  413.  
  414. /**********************************************************************/
  415. // Initialize number of channels
  416. void I_SetChannels (void)
  417. {
  418. }
  419.  
  420. /**********************************************************************/
  421. // Get raw data lump index for sound descriptor.
  422. int I_GetSfxLumpNum (sfxinfo_t *sfx)
  423. {
  424.   char namebuf[9];
  425.  
  426.   /* fprintf (stderr, "I_GetSfxLumpNum()\n"); */
  427.   sprintf(namebuf, "ds%s", sfx->name);
  428.   return W_GetNumForName(namebuf);
  429. }
  430.  
  431. /**********************************************************************/
  432. // Find chip cache entry used longest ago and re-use it.
  433. static int cache_chip_data (int id)
  434. {
  435.   int i, mini;
  436.   ULONG minage;
  437.   struct chip_cache_info *c;
  438.  
  439.   if (age == 0xfffffffe)
  440.     I_Error ("Age overflow in cache_chip_data()");
  441.   minage = 0xffffffff;
  442.   mini = 0;
  443.   for (i = 0; i < CHIP_CACHE_SIZE; i++) {
  444.     c = &chip_cache_info[i];
  445.     if (c->id == id) {
  446.       c->age = age++;
  447.       return i;
  448.     }
  449.     if (c->age < minage) {
  450.       minage = c->age;
  451.       mini = i;
  452.     }
  453.   }
  454.   c = &chip_cache_info[mini];
  455.   if (c->chip_data != NULL) {
  456.     FreeMem (c->chip_data, c->len);
  457.     c->chip_data = NULL;
  458.   }
  459.   c->id = id;
  460.   c->age = age++;
  461.   if ((c->chip_data = AllocMem (lengths[id], MEMF_CHIP)) == NULL)
  462.     I_Error ("Out of CHIP memory allocating %d bytes", lengths[id]);
  463.   memcpy (c->chip_data, S_sfx[id].data, lengths[id]);
  464.   c->len = lengths[id];
  465.   return mini;
  466. }
  467.  
  468. /**********************************************************************/
  469. // Starts a sound in a particular sound channel.
  470. int I_StartSound (
  471.   int id,
  472.   int cnum,
  473.   int vol,
  474.   int sep,
  475.   int pitch,
  476.   int priority )
  477. {
  478.   struct channel_info *c;
  479.  
  480. /*  fprintf (stderr, "I_StartSound(%d,%d,%d,%d,%d,%d)\n", id, cnum, vol, sep,
  481.               pitch, priority); */
  482.  
  483.   if (asrvr_seg != NULL) {
  484.     I_StopSound(cnum);
  485.     Sfx_Start (S_sfx[id].data, cnum, changepitch ? freqs[pitch] : 11025,
  486.                vol<<3, sep, lengths[id]);
  487.     return cnum;
  488.   }
  489.  
  490.   if (!audio_is_open)
  491.     return 1;
  492.   I_StopSound (cnum);
  493.   c = &channel_info[cnum];
  494.   c->audio_io->ioa_Request.io_Command = CMD_WRITE;
  495.   c->audio_io->ioa_Request.io_Flags = ADIOF_PERVOL;
  496.   c->audio_io->ioa_Data = &chip_cache_info[cache_chip_data (id)].chip_data[8];
  497.   c->audio_io->ioa_Length = lengths[id] - 8;
  498.   c->audio_io->ioa_Period = period_table[pitch];
  499.   c->audio_io->ioa_Volume = vol << 2;
  500.   c->audio_io->ioa_Cycles = 1;
  501.   BeginIO ((struct IORequest *)c->audio_io);
  502.   c->sound_in_progress = TRUE;
  503.   return cnum;
  504. }
  505.  
  506. /**********************************************************************/
  507. // Stops a sound channel.
  508. void I_StopSound(int handle)
  509. {
  510.   /* fprintf (stderr, "I_StopSound(%d)\n", handle); */
  511.  
  512.   if (asrvr_seg != NULL) {
  513.     Sfx_Stop(handle);
  514.     return;
  515.   }
  516.  
  517.   if (!audio_is_open)
  518.     return;
  519.   if (channel_info[handle].sound_in_progress) {
  520.     AbortIO ((struct IORequest *)channel_info[handle].audio_io);
  521.     WaitPort (channel_info[handle].audio_mp);
  522.     GetMsg (channel_info[handle].audio_mp);
  523.     channel_info[handle].sound_in_progress = FALSE;
  524.   }
  525. }
  526.  
  527. /**********************************************************************/
  528. // Called by S_*() functions
  529. //  to see if a channel is still playing.
  530. // Returns 0 if no longer playing, 1 if playing.
  531. int I_SoundIsPlaying(int handle)
  532. {
  533.   /* fprintf (stderr, "I_SoundIsPlaying(%d)\n", handle); */
  534.  
  535.   if (asrvr_seg != NULL) {
  536.     return Sfx_Done(handle) ? 1 : 0;
  537.   }
  538.  
  539.   if (!audio_is_open)
  540.     return 0;
  541.   if (channel_info[handle].sound_in_progress) {
  542.     if (CheckIO ((struct IORequest *)channel_info[handle].audio_io)) {
  543.       WaitPort (channel_info[handle].audio_mp);  /* clears signal & returns immediately */
  544.       GetMsg (channel_info[handle].audio_mp);
  545.       channel_info[handle].sound_in_progress = FALSE;
  546.       return 0;
  547.     } else {
  548.       return 1;
  549.     }
  550.   }
  551.   return 0;
  552. }
  553.  
  554. /**********************************************************************/
  555. // Updates the volume, separation,
  556. //  and pitch of a sound channel.
  557. void
  558. I_UpdateSoundParams
  559. ( int        handle,
  560.   int        vol,
  561.   int        sep,
  562.   int        pitch )
  563. {
  564. /*
  565.   fprintf (stderr, "I_UpdateSoundParams(%d,%d,%d,%d)\n", handle, vol,
  566.            sep, pitch);
  567. */
  568.  
  569.   if (asrvr_seg != NULL) {
  570.     Sfx_Update(handle, changepitch ? freqs[pitch] : 11025, vol<<3, sep);
  571.     return;
  572.   }
  573.  
  574.   if (!audio_is_open)
  575.     return;
  576.   if (channel_info[handle].sound_in_progress) {
  577.     audio_io->ioa_Request.io_Command = ADCMD_PERVOL;
  578.     audio_io->ioa_Request.io_Flags = ADIOF_PERVOL;
  579.     audio_io->ioa_Request.io_Unit = (struct Unit *)(1 << handle);
  580.     audio_io->ioa_Period = period_table[pitch];
  581.     audio_io->ioa_Volume = vol << 2;
  582.     BeginIO ((struct IORequest *)audio_io);
  583.     WaitPort (audio_mp);
  584.     GetMsg (audio_mp);
  585.   }
  586. }
  587.  
  588.  
  589. /**********************************************************************/
  590. /**********************************************************************/
  591. //
  592. // MUSIC API.
  593. //
  594.  
  595. static int looping=0;
  596. static int musicdies=-1;
  597.  
  598. static int music_okay = 0;
  599.  
  600. /**********************************************************************/
  601. //
  602. //  MUSIC I/O
  603. //
  604. void I_InitMusic(void)
  605. {
  606. //  fprintf (stderr, "I_InitMusic()\n");
  607.  
  608.   if (M_CheckParm("-music") && (asrvr_seg != NULL))
  609.     music_okay = 1;
  610. }
  611.  
  612. /**********************************************************************/
  613. void I_ShutdownMusic(void)
  614. {
  615. //  fprintf (stderr, "I_ShutdownMusic()\n");
  616. }
  617.  
  618. /**********************************************************************/
  619. // Volume.
  620. void I_SetMusicVolume(int volume)
  621. {
  622. //  fprintf (stderr, "I_SetMusicVolume(%d)\n", volume);
  623.   snd_MusicVolume = volume;
  624.  
  625.   if (music_okay) {
  626.     Mus_SetVol((volume<<2)+4);
  627.   }
  628. }
  629.  
  630. /**********************************************************************/
  631. // PAUSE game handling.
  632. void I_PauseSong(int handle)
  633. {
  634. //  fprintf (stderr, "I_PauseSong(%d)\n", handle);
  635.  
  636.   if (music_okay) {
  637.     Mus_Pause(handle);
  638.   }
  639. }
  640.  
  641. /**********************************************************************/
  642. void I_ResumeSong(int handle)
  643. {
  644. //  fprintf (stderr, "I_ResumeSong(%d)\n", handle);
  645.  
  646.   if (music_okay) {
  647.     Mus_Resume(handle);
  648.   }
  649. }
  650.  
  651. /**********************************************************************/
  652. // Registers a song handle to song data.
  653. int I_RegisterSong(void *data)
  654. {
  655. //  fprintf (stderr, "I_RegisterSong(%08x)\n", data);
  656.  
  657.   if (music_okay) {
  658.     return Mus_Register(data);
  659.   } else
  660.     return 2;
  661. }
  662.  
  663. /**********************************************************************/
  664. // Called by anything that wishes to start music.
  665. //  plays a song, and when the song is done,
  666. //  starts playing it again in an endless loop.
  667. // Horrible thing to do, considering.
  668. void
  669. I_PlaySong
  670. ( int        handle,
  671.   int        looping )
  672. {
  673. //  fprintf (stderr, "I_PlaySong(%d,%d)\n", handle, looping);
  674.  
  675.   if (music_okay) {
  676.     Mus_Play(handle, looping);
  677.   }
  678.  
  679.   musicdies = gametic + TICRATE*30;
  680. }
  681.  
  682. /**********************************************************************/
  683. // Stops a song over 3 seconds.
  684. void I_StopSong(int handle)
  685. {
  686. //  fprintf (stderr, "I_StopSong(%d)\n", handle);
  687.  
  688.   if (music_okay) {
  689.     Mus_Stop(handle);
  690.   }
  691.   musicdies = 0;
  692. }
  693.  
  694. /**********************************************************************/
  695. // See above (register), then think backwards
  696. void I_UnRegisterSong(int handle)
  697. {
  698. //  fprintf (stderr, "I_UnRegisterSong(%d)\n", handle);
  699.  
  700.   if (music_okay) {
  701.     Mus_Unregister(handle);
  702.   }
  703.   handle = 0;
  704. }
  705.  
  706. /**********************************************************************/
  707.  
  708.  
  709. /**********************************************************************/
  710. void _STDaudio_cleanup (void)
  711. {
  712.   I_ShutdownSound ();
  713.   I_ShutdownMusic ();
  714. }
  715.  
  716. /**********************************************************************/
  717.